home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 5 / Example 5.1 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  6.3 KB  |  244 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 5.1: Camera Example                                //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "mesh.h"
  10. #include "camera.h"
  11.  
  12. class APPLICATION
  13. {
  14.     public:
  15.         APPLICATION();
  16.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  17.         HRESULT Update(float deltaTime);
  18.         HRESULT Render();
  19.         HRESULT Cleanup();
  20.         HRESULT Quit();
  21.  
  22.     private:
  23.         IDirect3DDevice9* m_pDevice; 
  24.         CAMERA m_camera;
  25.         MESH *m_pMesh;
  26.  
  27.         D3DLIGHT9 m_light;
  28.         HWND m_mainWindow;
  29.         ID3DXFont *m_pFont;
  30. };
  31.  
  32. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  33. {
  34.     APPLICATION app;
  35.  
  36.     if(FAILED(app.Init(hInstance, 800, 600, true)))
  37.         return 0;
  38.  
  39.     MSG msg;
  40.     memset(&msg, 0, sizeof(MSG));
  41.     int startTime = timeGetTime(); 
  42.  
  43.     while(msg.message != WM_QUIT)
  44.     {
  45.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  46.         {
  47.             ::TranslateMessage(&msg);
  48.             ::DispatchMessage(&msg);
  49.         }
  50.         else
  51.         {    
  52.             int t = timeGetTime();
  53.             float deltaTime = (t - startTime)*0.001f;
  54.  
  55.             app.Update(deltaTime);
  56.             app.Render();
  57.  
  58.             startTime = t;
  59.         }
  60.     }
  61.  
  62.     app.Cleanup();
  63.  
  64.     return msg.wParam;
  65. }
  66.  
  67. APPLICATION::APPLICATION()
  68. {
  69.     m_pDevice = NULL; 
  70.     m_pMesh = NULL;
  71.     m_mainWindow = 0;
  72.  
  73.     srand(GetTickCount());
  74. }
  75.  
  76. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  77. {
  78.     debug.Print("Application initiated");
  79.  
  80.     //Create Window Class
  81.     WNDCLASS wc;
  82.     memset(&wc, 0, sizeof(WNDCLASS));
  83.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  84.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  85.     wc.hInstance     = hInstance;
  86.     wc.lpszClassName = "D3DWND";
  87.  
  88.     //Register Class and Create new Window
  89.     RegisterClass(&wc);
  90.     m_mainWindow = CreateWindow("D3DWND", "Example 5.1: Camera Example", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  91.     SetCursor(NULL);
  92.     ShowWindow(m_mainWindow, SW_SHOW);
  93.     UpdateWindow(m_mainWindow);
  94.  
  95.     //Create IDirect3D9 Interface
  96.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  97.  
  98.     if(d3d9 == NULL)
  99.     {
  100.         debug.Print("Direct3DCreate9() - FAILED");
  101.         return E_FAIL;
  102.     }
  103.  
  104.     //Check that the Device supports what we need from it
  105.     D3DCAPS9 caps;
  106.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  107.  
  108.     //Hardware Vertex Processing or not?
  109.     int vp = 0;
  110.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  111.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  112.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  113.  
  114.     //Check vertex & pixelshader versions
  115.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  116.     {
  117.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  118.     }
  119.  
  120.     //Set D3DPRESENT_PARAMETERS
  121.     D3DPRESENT_PARAMETERS d3dpp;
  122.     d3dpp.BackBufferWidth            = width;
  123.     d3dpp.BackBufferHeight           = height;
  124.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  125.     d3dpp.BackBufferCount            = 1;
  126.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  127.     d3dpp.MultiSampleQuality         = 0;
  128.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  129.     d3dpp.hDeviceWindow              = m_mainWindow;
  130.     d3dpp.Windowed                   = windowed;
  131.     d3dpp.EnableAutoDepthStencil     = true; 
  132.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  133.     d3dpp.Flags                      = 0;
  134.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  135.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  136.  
  137.     //Create the IDirect3DDevice9
  138.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  139.                                  vp, &d3dpp, &m_pDevice)))
  140.     {
  141.         debug.Print("Failed to create IDirect3DDevice9");
  142.         return E_FAIL;
  143.     }
  144.  
  145.     //Release IDirect3D9 interface
  146.     d3d9->Release();
  147.  
  148.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  149.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  150.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  151.  
  152.     //Create mesh
  153.     m_pMesh = new MESH("meshes/terrain.x", m_pDevice);
  154.  
  155.     //Init Camera
  156.     m_camera.Init(m_pDevice);
  157.  
  158.     //Create m_light
  159.     ::ZeroMemory(&m_light, sizeof(m_light));
  160.     m_light.Type      = D3DLIGHT_DIRECTIONAL;
  161.     m_light.Ambient   = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  162.     m_light.Diffuse   = D3DXCOLOR(0.9, 0.9, 0.9, 1.0f);
  163.     m_light.Specular  = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  164.     m_light.Direction = D3DXVECTOR3(0.7f, -0.3f, 0.0f);
  165.     m_pDevice->SetLight(0, &m_light);
  166.     m_pDevice->LightEnable(0, true);
  167.  
  168.     //Set sampler state
  169.     for(int i=0;i<4;i++)
  170.     {
  171.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  172.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  173.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  174.     }
  175.  
  176.     return S_OK;
  177. }
  178.  
  179. HRESULT APPLICATION::Update(float deltaTime)
  180. {
  181.     D3DXMATRIX  matWorld;
  182.     D3DXMatrixIdentity(&matWorld);
  183.     m_pDevice->SetTransform(D3DTS_WORLD, &matWorld);
  184.  
  185.     //Update Camera
  186.     m_camera.Update(deltaTime);
  187.  
  188.     if(KEYDOWN(VK_ESCAPE))
  189.         Quit();
  190.  
  191.     return S_OK;
  192. }    
  193.  
  194. HRESULT APPLICATION::Render()
  195. {
  196.     // Clear the viewport
  197.     m_pDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0L );
  198.  
  199.     // Begin the scene 
  200.     if(SUCCEEDED(m_pDevice->BeginScene()))
  201.     {
  202.         if(m_pMesh != NULL)
  203.             m_pMesh->Render();
  204.  
  205.         RECT r[] = {{10, 10, 0, 0}, {10, 30, 0, 0}, {10, 50, 0, 0}, {10, 70, 0, 0}};
  206.         m_pFont->DrawText(NULL, "A,W,S,D: Change Camera Angle", -1, &r[0], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  207.         m_pFont->DrawText(NULL, "Arrows: Move Focus", -1, &r[1], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  208.         m_pFont->DrawText(NULL, "+/-: Zoom in/out", -1, &r[2], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  209.         m_pFont->DrawText(NULL, "SHIFT, +/-: Change Radius", -1, &r[3], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  210.  
  211.         // End the scene.
  212.         m_pDevice->EndScene();
  213.         m_pDevice->Present(0, 0, 0, 0);
  214.     }
  215.  
  216.     return S_OK;
  217. }
  218.  
  219. HRESULT APPLICATION::Cleanup()
  220. {
  221.     try
  222.     {
  223.         if(m_pMesh != NULL)
  224.         {
  225.             delete m_pMesh;
  226.             m_pMesh = NULL;
  227.         }
  228.  
  229.         m_pFont->Release();
  230.         m_pDevice->Release();
  231.  
  232.         debug.Print("Application terminated");
  233.     }
  234.     catch(...){}
  235.  
  236.     return S_OK;
  237. }
  238.  
  239. HRESULT APPLICATION::Quit()
  240. {
  241.     ::DestroyWindow(m_mainWindow);
  242.     ::PostQuitMessage(0);
  243.     return S_OK;
  244. }